<!-- 横向柱状图 指定皇帝任期内所有国家情况  纵轴-国家  横轴-时间 -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <!-- 引入 ECharts 文件 -->
    <script src="echarts.min.js"></script>
    <script src="lodash.4.17.5.js"></script>
</head>

<body>
    <!-- 为 ECharts 准备一个具备大小（宽高）的 DOM -->
    <div id="main" style="height:850px;"></div>
    <script>
        function setBarData(strData, strName, strCountry) {
            // 基于准备好的dom，初始化echarts实例
            var myChart = echarts.init(document.getElementById('main'));

            // 柱状图数据源  格式为：GGGG:20:30@SSSS:30:30@TTTT:10@VVVV:60:30  国家:起始时间:结束时间
            var strTemp = strData.split("@");
            var len = strTemp.length;
            var countryLst = [];
            var timeLst = [];
            for (var i = 0; i < len; ++i) {
                var temp = strTemp[i].split(":");
                countryLst.push(temp[0]);
                var lstTemp = [];
                lstTemp.push(temp[1]);
                lstTemp.push(temp[2]);
                timeLst.push(lstTemp)
            }

            let option;

            const category = countryLst;
            name = '时间区间';
            const data = timeLst;
           
            let series = [];
            series = [...series, ...createSeries(data, name, true)];

            option = {
                title: {
                    text: strName + '时期周边国家信息'
                },
                color: ['dodgerblue', 'violet', 'orange'],
                legend: {
                    data: name
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: { // 坐标轴指示器，坐标轴触发有效
                        type: 'shadow' // 默认为直线，可选为：'line' | 'shadow'
                    },
                    formatter: function (params) {
                        var html = '';
                        var axisValue = '';
                        params.forEach(item => {
                            axisValue = item.axisValue;
                            const range = item.data.range;
                            html += item.marker + item.name + ': ' + range[0] + ' ~ ' + range[1] +
                                '<br/>';
                        })
                        const {
                            name,
                            data: {
                                range
                            }
                        } = params[0];
                        return axisValue + '<br/>' + html;
                    }
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    type: 'value'
                },
                yAxis: {
                    type: 'category',
                    axisLine: {
                        onZero: false
                    },
                    splitLine: {
                        show: false
                    },
                    data: category
                },
                series: series
            };

            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
        }

        // 轴数据处理
        function dataFormat(data, name) {
            let min = []; // 区间的最小值, 堆叠，透明
            let max = []; // 区间的最大值, 堆叠，显示
            let negative = []; // 负值处理，堆叠，显示负值的部分，max仅显示了正值的部分。特殊情况，区间最小值为负值，最大值为正值。
            let minLabel = []; // 显示区间的最小值的 label 数据，在 max 上通过 markpoint 实现，以控制 label 颜色值和显示的柱子颜色值一致，并且显示隐藏有效

            // 对数据排序，后面需要找到整组数据中最小值
            let sortData = _.cloneDeep(data);
            sortData.sort((a, b) => a[0] - b[0])

            data.forEach((item, i) => {

                // 取哪个值作为透明底层(从0开始)，[-min, +max]->0不需要透明; [-min, -max]->-max到0填充透明；[+min,+max]->0到+min填充透明
                min.push(item[1] <= 0 ? item[1] : item[0] <= 0 ? 0 : item[0]);
                // 主要处理[-min,+max]情况，填充显示-min的部分。其他情况不需要填充，为0。
                negative.push(item[1] <= 0 || item[0] >= 0 ? 0 : item[0]);

                // 横向：coord: [offsetx，y]，等同于 xAxis: offsetx, yAxis: y。其中，offsetx 表示偏移值，y 表示bar的索引。
                // 竖向：[x, offsety]
                const coord = [i, item[0]];
                minLabel.push({
                    value: item[0], // 对值进行格式化
                    coord: item[0] || sortData[0][0] ? coord : [], // 当最小值不为0的时候，都要显示
                })

                max.push({
                    // // 差值作为叠加值，在透明层的数据上叠加。[-min, +max]->0到max,不需要堆叠进行差值计算; [+min, +max]->+max - +min需要计算差值；[-min,-max]->-min - -max需要计算差值
                    value: item[1] <= 0 ? item[0] - item[1] : item[0] <= 0 ? item[1] : item[1] - item[
                        0],
                    range: item, // tooltip 显示
                    name, // legend 显示
                    label: {
                        formatter: '' + item[1], // 最终值作为显示值
                    },
                    itemStyle: {
                        color: item[2]
                    }
                })
            })

            return {
                min,
                max,
                negative,
                minLabel
            }
        }

        // 生成序列数据
        function createSeries(arr, name, showLabel) {
            let newSeries = [];

            const {
                min,
                max,
                minLabel,
                negative
            } = dataFormat(arr, name);

            const maxPosition = 'top';
            const minPosition = 'bottom';

            newSeries = [
                // 作为堆叠辅助，不显示
                {
                    type: 'bar',
                    stack: name,
                    tooltip: {
                        show: false
                    },
                    // 透明
                    itemStyle: {
                        barBorderColor: 'rgba(0,0,0,0)',
                        color: 'rgba(0,0,0,0)'
                    },
                    emphasis: {
                        itemStyle: {
                            barBorderColor: 'rgba(0,0,0,0)',
                            color: 'rgba(0,0,0,0)'
                        }
                    },
                    label: {
                        show: false,
                    },
                    data: min
                },
                // 当区间[负值，正值]时，用于显示负值的部分
                {
                    type: 'bar',
                    stack: name,
                    name: name, // 名称和max相同，保证柱子统一颜色
                    tooltip: {
                        show: false,
                    },
                    label: {
                        show: false,
                    },
                    data: negative,
                },
                // 用于显示正值的部分
                {
                    type: 'bar',
                    stack: name,
                    name: name,
                    tooltip: {
                        show: true,
                    },
                    label: {
                        show: false,
                        position: maxPosition,
                    },
                    markPoint: {
                        symbol: 'rect',
                        // 图形上面的小头隐藏
                        symbolSize: 0.000000000000001,
                        label: {
                            show: false,
                            position: minPosition,
                        },
                        data: minLabel
                    },
                    data: max,
                }
            ]
            return newSeries;
        }

        // setBarData("西汉:-187:-179", "高后吕雉", "西汉");
    </script>


</body>

</html>